#pragma once

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>

const std::string operations = "+-*/%";

class CalculateService
{
public:
    CalculateService()
    {
        _map = {
            {'+', [](int x, int y, int& code) -> int {
                code = 0;
                return x + y;
            }},
            {'-', [](int x, int y, int& code) -> int {
                code = 0;
                return x - y;
            }},
            {'*', [](int x, int y, int& code) -> int {
                code = 0;
                return x * y;
            }},
            {'/', [](int x, int y, int& code) -> int {
                if(y == 0) 
                {
                    code = -1;
                    return -1;
                }
                else 
                {
                    code = 0;
                    return x / y;
                }
            }},
            {'%', [](int x, int y, int& code) -> int {
                code = 0;
                return x % y;
            }}
        };
    }

    int doCalculate(int x, int y, char op, int& code)
    {
        return _map[op](x, y, code);
    }

    bool checkInput(const std::string& contentByteStream)
    {
        if(contentByteStream.find(" ") != std::string::npos)
        {
            std::cout << "bad space" << std::endl;
            std::cout << "usage: int opreation int, example: 1+1" << std::endl;
            return false;
        }
        if(getOperationPos(contentByteStream) == -1)
        {
            std::cout << "unknown operation" << std::endl;
            std::cout << "available opreation: + - * / %" << std::endl;
        }
        return true;
    }

    int getOperationPos(const std::string& contentByteStream)
    {
        if(_operationPos != -1) return _operationPos;
        int operationPos = -1;
        for(int i = 0; i < operations.size(); i++)
        {
            int pos = contentByteStream.find(operations[i]);
            if(pos != std::string::npos) operationPos = pos;
        }
        if(operationPos == -1)
        {
            std::cout << "unknown operation" << std::endl;
            std::cout << "available opreation: + - * / %" << std::endl;
            return -1;
        }
        _operationPos = operationPos;
        return operationPos;
    }

    void showResult(int result, int code)
    {
        if(code == -1) std::cout << "arithmetic exception" << std::endl;
        else std::cout << "result = " << result << std::endl;
    }

    ~CalculateService()
    {}
private:
    std::unordered_map<char, std::function<int(int, int, int&)>> _map;
    int _operationPos = -1;
};